package com.smart.community.commons.config;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import lombok.extern.slf4j.Slf4j;

/**
 * 全局Jackson配置类
 * 功能说明：
 * 1. 配置全局ObjectMapper，确保JSON序列化不包含类型信息
 * 2. 支持Java 8时间类型序列化
 * 3. 统一JSON序列化格式
 * 4. 解决类型信息注入导致的JSON嵌套问题
 * 5. 增强安全性，防止类型信息泄露
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2024-12-21
 */
@Slf4j
@Configuration
public class JacksonConfig {

    /**
     * 日期时间格式化器
     */
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 日期格式化器
     */
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
    /**
     * 时间格式化器
     */
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");

    /**
     * 配置全局ObjectMapper
     * 
     * @return ObjectMapper
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper objectMapper() {
        log.info("🔧 初始化Jackson ObjectMapper...");
        
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 配置序列化特性
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
        
        // 配置反序列化特性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
        objectMapper.configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true);
        objectMapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
        
        // 配置映射特性
        objectMapper.configure(MapperFeature.USE_GETTERS_AS_SETTERS, false);
        objectMapper.configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, false);
        objectMapper.configure(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS, true);
        
        // 配置解析特性
        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
        
        // 配置生成特性
        objectMapper.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false);
        objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false);
        
        // 设置包含策略
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        // 注册Java时间模块
        objectMapper.registerModule(javaTimeModule());
        
        // 注册自定义模块
        objectMapper.registerModule(customModule());
        
        log.info("✅ Jackson ObjectMapper初始化完成");
        return objectMapper;
    }
    
    /**
     * Java时间模块
     * 
     * @return JavaTimeModule
     */
    @Bean
    @ConditionalOnMissingBean
    public JavaTimeModule javaTimeModule() {
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        
        // 注册LocalDateTime序列化器和反序列化器
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER));
        
        // 注册LocalDate序列化器和反序列化器
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER));
        
        // 注册LocalTime序列化器和反序列化器
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
        
        return javaTimeModule;
    }
    
    /**
     * 自定义模块
     * 
     * @return SimpleModule
     */
    @Bean(name = "customModule")
    public SimpleModule customModule() {
        SimpleModule customModule = new SimpleModule();
        
        // 注册BigDecimal序列化器
        customModule.addSerializer(BigDecimal.class, new JsonSerializer<BigDecimal>() {
            @Override
            public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                if (value != null) {
                    gen.writeString(value.stripTrailingZeros().toPlainString());
                }
            }
        });
        
        // 注册BigDecimal反序列化器
        customModule.addDeserializer(BigDecimal.class, new JsonDeserializer<BigDecimal>() {
            @Override
            public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                String value = p.getValueAsString();
                return value != null ? new BigDecimal(value) : null;
            }
        });
        
        return customModule;
    }
    
    /**
     * 获取日期时间格式化器
     * 
     * @return 日期时间格式化器
     */
    public static DateTimeFormatter getDateTimeFormatter() {
        return DATE_TIME_FORMATTER;
    }
    
    /**
     * 获取日期格式化器
     * 
     * @return 日期格式化器
     */
    public static DateTimeFormatter getDateFormatter() {
        return DATE_FORMATTER;
    }
    
    /**
     * 获取时间格式化器
     * 
     * @return 时间格式化器
     */
    public static DateTimeFormatter getTimeFormatter() {
        return TIME_FORMATTER;
    }
} 